package com.hyk.learning.rateLimit.Impl;

import com.hyk.learning.rateLimit.RateLimit;
import sun.awt.geom.AreaOp;

/**
 * @className: TokenBucketRateLimitImpl
 * @author: hyk199710
 * @description: 令牌桶限流算法
 * @date: 2024/9/5 23:48
 */
public class TokenBucketRateLimitImpl implements RateLimit {

    //产生一个令牌时间ms
    private static int RATE;
    //桶容量
    private static int CAPACITY;
    //当前桶容量
    private volatile int curCapcity;
    //时间戳
    private volatile long timeStamp = System.currentTimeMillis();

    public TokenBucketRateLimitImpl(int rate, int capcity){
        RATE = rate;
        CAPACITY = capcity;
        this.curCapcity = capcity;
    }
    @Override
    public boolean getToken() {
        if(this.curCapcity > 0){
            this.curCapcity--;
            return true;
        }
        //如果距离上一次的请求的时间大于RATE的时间
        long current = System.currentTimeMillis();
        if(current - timeStamp >= RATE){
            //计算这段时间间隔中生成的令牌，如果>2,桶容量加上（计算的令牌-1）
            //如果==1，就不做操作（因为这一次操作要消耗一个令牌）
            if((current-timeStamp)/RATE>=2){
                curCapcity+=(int)(current-timeStamp)/RATE-1;
            }
            //保持桶内令牌容量<=10
            if(curCapcity>CAPACITY) curCapcity=CAPACITY;
            //刷新时间戳为本次请求
            timeStamp=current;
            return true;
        }
        //获得不到，返回false
        return false;
    }
}
